package com.baihui.crm;

import com.taobao.api.TaobaoObject;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.lang.reflect.Field;
import java.net.*;
import java.security.MessageDigest;
import java.security.Security;
import java.util.*;

/**
 * 
 */
public class DES {

	private static final String Algorithm = "DESede"; // 定义加密算法,可用
	// DES,DESede,Blowfish
	// keybyte为加密密钥，长度为24字节
	// src为被加密的数据缓冲区（源）
	private static String KEY = "baihuiCrm888baihuiCrm888";

	static {
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
	}
	private static final char[] map1 = new char[64];
	static {
		int i = 0;
		for (char c = 'A'; c <= 'Z'; c++)
			map1[i++] = c;
		for (char c = 'a'; c <= 'z'; c++)
			map1[i++] = c;
		for (char c = '0'; c <= '9'; c++)
			map1[i++] = c;
		map1[i++] = '+';
		map1[i++] = '/';
	}

	private static final byte[] map2 = new byte[128];
	static {
		for (int i = 0; i < map2.length; i++)
			map2[i] = -1;
		for (int i = 0; i < 64; i++)
			map2[map1[i]] = (byte) i;
	}

	private static String encode(byte[] in) {
		return new String(encode(in, 0, in.length));
	}

	private static char[] encode(byte[] in, int iOff, int iLen) {
		int oDataLen = (iLen * 4 + 2) / 3; // output length without padding
		int oLen = ((iLen + 2) / 3) * 4; // output length including padding
		char[] out = new char[oLen];
		int ip = iOff;
		int iEnd = iOff + iLen;
		int op = 0;
		while (ip < iEnd) {
			int i0 = in[ip++] & 0xff;
			int i1 = ip < iEnd ? in[ip++] & 0xff : 0;
			int i2 = ip < iEnd ? in[ip++] & 0xff : 0;
			int o0 = i0 >>> 2;
			int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
			int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
			int o3 = i2 & 0x3F;
			out[op++] = map1[o0];
			out[op++] = map1[o1];
			out[op] = op < oDataLen ? map1[o2] : '=';
			op++;
			out[op] = op < oDataLen ? map1[o3] : '=';
			op++;
		}
		return out;
	}

	private static byte[] decode(String in) {
		char[] bytes = in.toCharArray();
		return decode(bytes, 0, bytes.length);
	}

	private static byte[] decode(char[] in, int iOff, int iLen) {
		if (iLen % 4 != 0)
			throw new IllegalArgumentException(
					"Length of Base64 encoded input string is not a multiple of 4.");
		while (iLen > 0 && in[iOff + iLen - 1] == '=')
			iLen--;
		int oLen = (iLen * 3) / 4;
		byte[] out = new byte[oLen];
		int ip = iOff;
		int iEnd = iOff + iLen;
		int op = 0;
		while (ip < iEnd) {
			int i0 = in[ip++];
			int i1 = in[ip++];
			int i2 = ip < iEnd ? in[ip++] : 'A';
			int i3 = ip < iEnd ? in[ip++] : 'A';
			if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
				throw new IllegalArgumentException(
						"Illegal character in Base64 encoded data.");
			int b0 = map2[i0];
			int b1 = map2[i1];
			int b2 = map2[i2];
			int b3 = map2[i3];
			if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
				throw new IllegalArgumentException(
						"Illegal character in Base64 encoded data.");
			int o0 = (b0 << 2) | (b1 >>> 4);
			int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
			int o2 = ((b2 & 3) << 6) | b3;
			out[op++] = (byte) o0;
			if (op < oLen)
				out[op++] = (byte) o1;
			if (op < oLen)
				out[op++] = (byte) o2;
		}
		return out;
	}

	private static byte[] encryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
			// 加密
			Cipher c1 = Cipher.getInstance(Algorithm);
			c1.init(Cipher.ENCRYPT_MODE, deskey);
			return c1.doFinal(src);// 在单一方面的加密或解密
		} catch (java.security.NoSuchAlgorithmException e1) {
			// TODO: handle exception
			e1.printStackTrace();

		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	// keybyte为加密密钥，长度为24字节
	// src为加密后的缓冲区
	private static byte[] decryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
			// 解密
			Cipher c1 = Cipher.getInstance(Algorithm);
			c1.init(Cipher.DECRYPT_MODE, deskey);
			return c1.doFinal(src);

		} catch (java.security.NoSuchAlgorithmException e1) {
			// TODO: handle exception
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	// 转换成十六进制字符串

	private static String byte2Hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1) {
				hs = hs + "0" + stmp;
			} else {
				hs = hs + stmp;
			}
			if (n < b.length - 1)
				hs = hs + ":";
		}

		return hs.toUpperCase();
	}

	// public static void desSignature(String pw) {
	public static void main(String[] pw) throws UnsupportedEncodingException {
		String d= encodePw("123456");
//		System.out.println(d);
//
//        String encode = URLEncoder.encode(d,"UTF-8");
//        System.out.println(encode);
//
//        String decode = URLDecoder.decode(encode,"UTF-8");
//        System.out.println(decode);
//
//		String s = decodePw(decode);
		System.out.println(d);
		System.out.println(DES.decodePw(d));

	}

	public static String encodePw(String password) {

		byte[] keyBytes = KEY.getBytes();

		Date date = new Date();
		Long time = date.getTime();
		String szSrc = time + "$" + password;
		byte[] encoded = encryptMode(keyBytes, szSrc.getBytes());
		String s = encode(encoded);
		return s;
//		return URLEncoder.encode(s);
	}

	public static String decodePw(String password) {

		byte[] keyBytes = KEY.getBytes();

		byte[] encoded = decryptMode(keyBytes, decode(password));

		String s = new String(encoded);
		int nu = s.indexOf("$");
		String pw = "";
		if (nu != -1) {
			pw = s.substring(nu + 1);
		}
		return pw;
	}

	/**
	 * 停止一分钟
	 */
	public static void stopOneMinute() {
		try {
			// Thread.sleep(1000l * 10l);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 访问url
	 * 
	 * @param requestUrl
	 * @throws Exception
	 */
	public static void accessUrl(String requestUrl) throws Exception {
		URL url = null;
		URLConnection urlConnection = null;
		StringBuffer document = new StringBuffer();

		url = new URL(requestUrl);
		urlConnection = url.openConnection();
		urlConnection.connect();

	}

	public static List subList(List allBuyer, int startIndex, int count) {
		List ret = new ArrayList();
		for (int i = startIndex; i < (startIndex + count); i++) {
			if (i < allBuyer.size()) {
				ret.add(allBuyer.get(i));
			} else {
				break;
			}
		}
		return ret;
	}

	public String getTableName(TaobaoObject info) {
		return "T" + info.getClass().getSimpleName();
	}

	public static Field[] getAllField(Class aClass) {
		List list = new ArrayList();
		getAllField(aClass, list);
		return (Field[]) list.toArray(new Field[] {});
	}

	private static void getAllField(Class aClass, List<Field> fieldList) {
		Field[] fields = aClass.getDeclaredFields();
		for (Field field : fields) {
			if (field.getName().equals("serialVersionUID"))
				continue;
			fieldList.add(field);
		}
		if (!aClass.getSuperclass().getSimpleName().toUpperCase()
				.equals("TAOBAOOBJECT")) {
			getAllField(aClass.getSuperclass(), fieldList);
		}
	}

	public static boolean isExist(String fieldName, String[] excludefield) {
		for (String excludeName : excludefield) {
			if (excludeName.equals(fieldName)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 新的md5签名，首尾放secret。
	 * 
	 * @param secret
	 *            分配给您的APP_SECRET
	 */
	public static String md5Signature(String secret) {
		String result = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			result = byte2hex(md.digest(secret.getBytes("utf-8")));
		} catch (Exception e) {
			throw new RuntimeException("sign error !");
		}
		return result;
	}

	/**
	 * 新的md5签名，首尾放secret。
	 * 
	 * @param secret
	 *            分配给您的APP_SECRET
	 */
	public static String md5Signature(TreeMap<String, String> params,
			String secret) {
		String result = null;
		StringBuffer orgin = getBeforeSign(params, new StringBuffer(secret));
		if (orgin == null)
			return result;
		orgin.append(secret);
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			result = byte2hex(md.digest(orgin.toString().getBytes("utf-8")));
		} catch (Exception e) {
			throw new RuntimeException("sign error !");
		}
		return result;
	}

	/**
	 * 二行制转字符串
	 */
	private static String byte2hex(byte[] b) {
		StringBuffer hs = new StringBuffer();
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs.append("0").append(stmp);
			else
				hs.append(stmp);
		}
		return hs.toString().toUpperCase();
	}

	/**
	 * 添加参数的封装方法
	 */
	private static StringBuffer getBeforeSign(TreeMap<String, String> params,
			StringBuffer orgin) {
		if (params == null)
			return null;
		Map<String, String> treeMap = new TreeMap<String, String>();
		treeMap.putAll(params);
		Iterator<String> iter = treeMap.keySet().iterator();
		while (iter.hasNext()) {
			String name = (String) iter.next();
			orgin.append(name).append(params.get(name));
		}
		return orgin;
	}

	/**
	 * 连接到TOP服务器并获取数据
	 */
	public static String getResult(String urlStr, String content) {
		URL url = null;
		HttpURLConnection connection = null;

		try {
			url = new URL(urlStr);
			connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.connect();

			DataOutputStream out = new DataOutputStream(
					connection.getOutputStream());
			out.write(content.getBytes("utf-8"));
			out.flush();
			out.close();

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					connection.getInputStream(), "utf-8"));
			StringBuffer buffer = new StringBuffer();
			String line = "";
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			reader.close();
			return buffer.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
		}
		return null;
	}
	



}
